home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / wnos / wn941101 / analmem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-20  |  19.2 KB  |  565 lines

  1. /*======================================================================*
  2. *  File Name:  analmem.c                                                *
  3. *  Purpose  :  analysis of various files produced by NOS debug          *
  4. *              informations                                             *
  5. *                                                                       *
  6. *                                                                       *
  7. *  __first,    2      __first ptr                                       *
  8. *  __last ,    2      __last  ptr                                       *
  9. *  cret   ,    4      error position                                    *
  10. *  cret-4 ,   16     suspected header                                   *
  11. *  Curproc,    4                                                        *
  12. *  Rdytab ,    4                                                        *
  13. *  Susptab,    4                                                        *
  14. *  Waittab, 16*4                                                        *
  15. *  Timers ,    4     head of timerchain                                 *
  16. *  Nsessions,  2                                                        *
  17. *  Sessions,   sizeof(struct session)*NSESSIONS                         *
  18. *  &_streams,  16*sizeof(FILE))                                         *
  19. *  Date          Name      Description                                  *
  20. *  ----          ----      -----------                                  *
  21. *  09-Apr-1991   AA6HM     first hack                                   *
  22. *  11-Apr-1991   AA6HM     expanded to format crashdumps                *
  23. *=======================================================================*/
  24.  
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <io.h>
  29. #include <dos.h> /* MK_FP*/
  30. #include <ctype.h>
  31. #define MSDOS   1
  32. #define DK5DC   1
  33. #define MDEBUG  1
  34.  
  35. #include "global.h"
  36. #include "proc.h"
  37. #include "timer.h"
  38. #include "session.h"
  39.  
  40. #define EOF     (-1)
  41. #define PARA    16
  42. /*----------------------------------------------------------------------*
  43. *-----------------------------------------------------------------------*/
  44. typedef struct   {
  45.    unsigned char marker;
  46.    unsigned char min;
  47.    unsigned char hour;
  48.    unsigned char hund;
  49.    unsigned char sek;
  50.    unsigned seg;
  51.    unsigned nopara;
  52.    unsigned prevseg;
  53.    unsigned line;
  54.    char file[10];
  55. }Record;
  56.  
  57. /*----------------------------------------------------------------------*
  58. *-----------------------------------------------------------------------*/
  59. typedef struct   {
  60.    unsigned line;
  61.    char file[10];
  62. }Ainf;
  63.  
  64. typedef struct   {
  65.    unsigned first;                      /* start of heap                */
  66.    unsigned last;                       /* last allocated segment       */
  67.    unsigned dummy;
  68.    unsigned error;                      /* segment of suspected error   */
  69.    unsigned size;                       /* size of segment              */
  70.    unsigned prev;                       /* linkage                      */
  71.    unsigned line;                       /* linenumber                   */
  72.    char file[10];                       /* file                         */
  73. }Dumprec;
  74.  
  75.  
  76.  
  77. static int     opterr = 1;
  78. static int     optind = 1;
  79. static int     optopt;
  80. static char    *optarg;
  81.  
  82. void usage(void);
  83. int main(int argc,char **argv);
  84. static void near formatdump(FILE *fpi,FILE *fpo);
  85. static void near formatrecord(FILE *fpi,FILE *fpo);
  86. static void fmtline(unsigned addr,char *buf,unsigned len,char *line);
  87. static void ctohex(register char *buf,register unsigned c);
  88. static void near dline(FILE *fp);
  89. static void near xline(FILE *fp);
  90. static void * near fmtproc(void far *,FILE *fpi,FILE *fpo,char *name);
  91. static void near fmtsession(int no,long spos,FILE *fpi,FILE *fpo);
  92. static char * near getname(FILE *fpi,void *p);
  93.  
  94. main(int argc,char **argv)
  95. {
  96. FILE *fpi,*fpo;
  97.  
  98. char buf[80],*cp;
  99. int dump=0;
  100. char *srcn=0,c;
  101.  
  102.    printf("\nDump Format utility %s,%s by DK5DC/AA6HM\n",__DATE__,__TIME__);
  103.    if (argc <2)
  104.       usage();
  105.  
  106.    while((c = getopt(argc,argv,"d:m:")) != EOF){
  107.       switch(c)   {
  108.          case 'd':
  109.             srcn = strdup(optarg);
  110.             dump = 1;
  111.             break;
  112.          case 'm':
  113.             srcn = strdup(optarg);
  114.             break;
  115.       }
  116.    }
  117.    /*-------------------------------------------------------------------*
  118.    *--------------------------------------------------------------------*/
  119.    if (srcn==0)
  120.       srcn = strdup(argv[1]);
  121.    if ((fpi = fopen(srcn,"rb"))==0)   {
  122.       printf("Unable to open file %s\n");
  123.       exit(1);
  124.    }
  125.  
  126.    if ((cp = strchr(srcn,'.'))!=0)   {
  127.       *cp = 0;
  128.    }
  129.    sprintf(buf,"%s.out",srcn);
  130.    fpo = fopen(buf,"w+");
  131.    if (dump) {
  132.       formatdump(fpi,fpo);
  133.    } else   {
  134.       formatrecord(fpi,fpo);
  135.    } /* endif */
  136.    fclose(fpi);
  137.    fclose(fpo);
  138.  
  139.    return 0;
  140. }
  141.  
  142.  
  143. Dumprec drec;
  144. long fdstart;
  145. static char *tst[] =   {
  146.    "Stopped",
  147.    "Running",
  148.    "Expired"
  149. };
  150. /*----------------------------------------------------------------------*
  151. *-----------------------------------------------------------------------*/
  152. static void near formatdump(FILE *fpi,FILE *fpo)
  153. {
  154. char buf[16],line[81];
  155. char dbuf[1024];
  156. void far *bp,far *cproc;
  157. unsigned addr;
  158. unsigned cadr,i,nosess;
  159. long wtpos,sesstart;
  160. char *inbuf,*outbuf;
  161. struct timer ts;
  162.  
  163.    if ((inbuf = malloc(32767))!=0)
  164.       setvbuf(fpi,inbuf,_IOFBF,32767);
  165.    if ((outbuf = malloc(32767))!=0)
  166.       setvbuf(fpo,outbuf,_IOFBF,32767);
  167.  
  168.    /*-------------------------------------------------------------------*
  169.    *--------------------------------------------------------------------*/
  170.    fread(&drec,sizeof(drec),1,fpi);
  171.    fprintf(fpo,"HeapStart: 0x%04x Heapend: 0x%04X\n",drec.first,drec.last);
  172.    printf(     "HeapStart: 0x%04X Heapend: 0x%04X\n",drec.first,drec.last);
  173.    if (stricmp(drec.file,"SnapDump"))   {
  174.       fprintf(fpo,"ErrBlk   : 0x%04X Size   : 0x%04X File: %s Line: %04u\n",
  175.           drec.error,drec.size,drec.file,drec.line);
  176.       printf("ErrBlk   : 0x%04X Size   : 0x%04X File: %s Line: %04u",
  177.           drec.error,drec.size,drec.file,drec.line);
  178.    }else  {
  179.       fprintf(fpo,"File: %s \n",drec.file);
  180.       printf("File: %s \n",drec.file);
  181.    }
  182.    dline(fpo);
  183.    /*-------------------------------------------------------------------*
  184.    *--------------------------------------------------------------------*/
  185.    fread(&cproc,sizeof(void far *),1,fpi);
  186.    fprintf(fpo,"\nCurproc :%Fp",cproc);
  187.    fread(&bp,sizeof(void far *),1,fpi);
  188.    fprintf(fpo,"  Rdytab :%Fp",bp);
  189.    fread(&bp,sizeof(void far *),1,fpi);
  190.    fprintf(fpo,"   Susptab :%Fp",bp);
  191.    /*-------------------------------------------------------------------*
  192.    *--------------------------------------------------------------------*/
  193.    dline(fpo);
  194.    fprintf(fpo,"\nWaittab:");
  195.    wtpos = ftell(fpi);
  196.    for (i=0;i<4;i++) {
  197.       fread(&bp,sizeof(void far *),1,fpi);
  198.       fprintf(fpo,"\n    %Fp",bp);
  199.       fread(&bp,sizeof(void far *),1,fpi);
  200.       fprintf(fpo,"    %Fp",bp);
  201.       fread(&bp,sizeof(void far *),1,fpi);
  202.       fprintf(fpo,"    %Fp",bp);
  203.       fread(&bp,sizeof(void far *),1,fpi);
  204.       fprintf(fpo,"    %Fp",bp);
  205.    }
  206.    dline(fpo);
  207.    /*-------------------------------------------------------------------*
  208.    * format the timers  ...to be implemented                            *
  209.    *--------------------------------------------------------------------*/
  210.    fprintf(fpo,"\nTimer    State    start    count    func      arg\n");
  211.    fprintf(fpo,"----------------------------------------------------------\n");
  212.    do   {
  213.       fread(&ts,sizeof(struct timer ),1,fpi);  /* get head of timer address    */
  214.       fprintf(fpo,"%-8.8s %-8.8s %08ld %08ld %Fp %Fp\n",
  215.           ts.tname,tst[ts.state],ts.duration/MSPTICK,ts.expiration/MSPTICK,ts.func,ts.arg);
  216.    }while(ts.next);
  217.    /*-------------------------------------------------------------------*
  218.    * format session descriptors, to be implemented                      *
  219.    *--------------------------------------------------------------------*/
  220.    fread(&nosess,2,1,fpi);               /* get number of sessions       */
  221.    sesstart = ftell(fpi);
  222.    fseek(fpi,nosess*sizeof(struct session),SEEK_CUR); /*skip*/
  223.    fread(dbuf,0x140,1,fpi);
  224.    /*-------------------------------------------------------------------*
  225.    * format active sessions                                             *
  226.    *--------------------------------------------------------------------*/
  227.    fdstart = ftell(fpi);
  228.    dline(fpo);
  229.    fmtsession(nosess,sesstart,fpi,fpo);
  230.    dline(fpo);
  231.     /* format processes*/
  232.    fprintf(fpo,"\nProcess  Address    Name           prev      next\n");
  233.    fprintf(fpo,"---------------------------------------------------------");
  234.    while ((cproc=fmtproc(cproc,fpi,fpo,"Current"))!=NULL); /*format curproc*/
  235.    /*-------------------------------------------------------------------*
  236.    *--------------------------------------------------------------------*/
  237.    fseek(fpi,wtpos,SEEK_SET);
  238.    for (i=0;i<4;i++) {
  239.       fread(&bp,sizeof(void far *),1,fpi);
  240.       while((bp = fmtproc(bp,fpi,fpo,"Waittab"))!=NULL); /*format curproc*/
  241.       fread(&bp,sizeof(void far *),1,fpi);
  242.       while((bp = fmtproc(bp,fpi,fpo,"Waittab"))!=NULL); /*format curproc*/
  243.       fread(&bp,sizeof(void far *),1,fpi);
  244.       while((bp = fmtproc(bp,fpi,fpo,"Waittab"))!=NULL); /*format curproc*/
  245.       fread(&bp,sizeof(void far *),1,fpi);
  246.       while((bp = fmtproc(bp,fpi,fpo,"Waittab"))!=NULL); /*format curproc*/
  247.    }
  248.    fprintf(fpo,"\n");
  249.    dline(fpo);
  250.    fseek(fpi,fdstart,SEEK_SET); /* for safety*/
  251.    fputc('\n',fpo);
  252.    cadr = drec.error;
  253.    for (addr = drec.first;addr<drec.last;addr++)   {
  254.       if (addr == cadr)   {
  255.          fprintf(fpo,"\n\n===================================================\n\n");
  256.       }
  257.       fread(buf,PARA,1,fpi);
  258.       fmtline(addr,buf,PARA,line);
  259.       fprintf(fpo,"%s\n",line);
  260.    }
  261. }
  262.  
  263. /*----------------------------------------------------------------------*
  264. *-----------------------------------------------------------------------*/
  265. static char *pstates[]   =   {
  266.   "READY",
  267.   "SUSPENDED",
  268.   "WAITING"
  269. };
  270.  
  271. static void * near fmtproc(void far *proc,FILE *fpi,FILE *fpo,char *name)
  272. {
  273. long savepos;
  274. long tpos;
  275. unsigned pseg;
  276. struct proc pr;
  277. char *np;
  278.  
  279.    if (proc == NULL)
  280.       return(NULL);
  281.  
  282.    savepos = ftell(fpi);
  283.    pseg = FP_SEG(proc);
  284.    tpos = pseg+1 - drec.first;
  285.    fseek(fpi,fdstart,SEEK_SET);
  286.    fseek(fpi,tpos*PARA,SEEK_CUR);
  287.    fread(&pr,sizeof(struct proc),1,fpi);
  288.    np = getname(fpi,pr.name);
  289.    fprintf(fpo,"\n%-8.8s %Fp  %-14.14s %Fp %Fp\n",name,proc,np,pr.prev,pr.next);
  290.    free(np);
  291.  
  292.    fprintf(fpo,"   Procsave:\n      sp: %04x   bp: %04x   Ip: %04x\n",
  293.        pr.env->j_sp,
  294.        pr.env->j_bp,
  295.        pr.env->j_ip);
  296.    fprintf(fpo,"      f : %04x   si: %04x   di: %04x\n",
  297.        pr.env->j_flag,
  298.        pr.env->j_si,
  299.        pr.env->j_di);
  300.    fprintf(fpo,"      cs: %04x   ds: %04x   es: %04x   ss: %04x\n",
  301.            pr.env->j_cs,
  302.            pr.env->j_ds,
  303.            pr.env->j_es,
  304.            pr.env->j_ss);
  305.    /*-------------------------------------------------------------------*
  306.    * print states                                                       *
  307.    *--------------------------------------------------------------------*/
  308.    fprintf(fpo,"   i_state: %02x,    State: %s",pr.i_state,pstates[pr.state]);
  309.    fprintf(fpo,"     EcbAddress : %Fp\n",pr.event);
  310.    /*-------------------------------------------------------------------*
  311.    * print stack and its size                                           *
  312.    *--------------------------------------------------------------------*/
  313.    fprintf(fpo,"   Stack  : %Fp   StackSize: %04x\n",pr.stack,pr.stksize);
  314.    /* print ptr to name*/
  315.    fprintf(fpo,"   *name  : %Fp\n",pr.name);
  316.    /* retval on return*/
  317.    fprintf(fpo,"   RetVal : %Fp\n",pr.retval);
  318.    /*-------------------------------------------------------------------*
  319.    * Alarmtimer                                                         *
  320.    *--------------------------------------------------------------------*/
  321.    fprintf(fpo,"   Alarmtimer, State=:  ");
  322.    if (pr.alarm.state ==0)
  323.       fprintf(fpo,"STOP");
  324.    else if (pr.alarm.state ==1)
  325.       fprintf(fpo,"RUN");
  326.    else if (pr.alarm.state == 2)
  327.       fprintf(fpo,"EXPIRE");
  328.    fprintf(fpo,",     Initial : %08ld  Remaining: %08ld\n",pr.alarm.duration,pr.alarm.expiration);
  329.    fprintf(fpo,"      Next    : %Fp Prev     : notdef\n",pr.alarm.next);
  330.    fprintf(fpo,"      Func    : %Fp Args     : %Fp\n",pr.alarm.func,pr.alarm.arg);
  331.    /* Outbuf & Sockets*/
  332.    fprintf(fpo,"\n   Outbuf : %Fp  Insock : %04d  Outsock %04d\n",pr.outbuf,pr.input,pr.output);
  333.    fprintf(fpo,"   Parg1  : %Fp  Parg2  : %Fp   iargs: %04d",pr.parg1,pr.parg2,pr.iarg);
  334.    fprintf(fpo,"   Freeargs : %s\n",pr.freeargs?"YES":"NO");
  335.    fseek(fpi,savepos,SEEK_SET);
  336.    if ( pr.next)
  337.       xline(fpo);
  338.    else
  339.       dline(fpo);
  340.    return(pr.next);
  341. }
  342.  
  343. static char * near getname(FILE *fpi,void *p)
  344. {
  345. long cpos,tpos;
  346. char buffer[80];
  347.  
  348.    if (p == NULL)
  349.       return(p);
  350.    cpos=ftell(fpi);
  351.    tpos = FP_SEG(p)+1 - drec.first;
  352.    fseek(fpi,fdstart,SEEK_SET);
  353.    fseek(fpi,tpos*PARA,SEEK_CUR);
  354.    fgets(buffer,80,fpi);
  355.    fseek(fpi,cpos,SEEK_SET);
  356.    return(strdup(buffer));
  357.  
  358. }
  359. /*----------------------------------------------------------------------*
  360. *-----------------------------------------------------------------------*/
  361. static char *Sestypes[] = {
  362.    "(unused)",
  363.    "Telnet",
  364.    "FTP",
  365.    "AX25",
  366.    "Finger",
  367.    "Ping",
  368.    "NET/ROM",
  369.    "Command",
  370.    "More",
  371.    "Hopcheck",
  372.    "Tip",
  373.    "PPP PAP",
  374.    "Trace",
  375.    "RawIF",
  376.    "Rlogin"
  377. };
  378.  
  379. static void near fmtsession(int no,long spos,FILE *fpi,FILE *fpo)
  380. {
  381. struct session ses;
  382. long curpos;
  383. int i;
  384. char *n;
  385.  
  386.    curpos = ftell(fpi);
  387.    fseek(fpi,spos,SEEK_SET);
  388.    fprintf(fpo,"\nSession      Type         Name");
  389.    for (i=0;i<no;i++)   {
  390.       fread(&ses,sizeof(struct session),1,fpi);
  391.       if (ses.type!=FREE)   {
  392.      n = getname(fpi,ses.name);
  393.      fprintf(fpo,"\nSession[%02d]  %-9.9s %-13.13s %Fp %Fp %Fp",
  394.          i,Sestypes[ses.type],n,ses.proc,ses.proc1,ses.proc2);
  395.      free(n);
  396.       }
  397.    }
  398.    fseek(fpi,curpos,SEEK_SET);
  399. }
  400. /*----------------------------------------------------------------------*
  401. *-----------------------------------------------------------------------*/
  402. static void near formatrecord(FILE *fpi,FILE *fpo)
  403. {
  404. char buf[80];
  405. Record rec;
  406. Ainf ai;
  407. char *inbuf,*outbuf;
  408.  
  409.    if ((inbuf = malloc(16384))!=0)
  410.       setvbuf(fpi,inbuf,_IOFBF,16384);
  411.    if ((outbuf = malloc(16384))!=0)
  412.       setvbuf(fpo,outbuf,_IOFBF,16384);
  413.  
  414.    fread(buf,64,1,fpi);                 /* overread the info            */
  415.    while (fread(&rec,sizeof(Record),1,fpi))   {
  416.       fprintf(fpo,"%s %04x %02d:%02d:%02d.%02d %04u %10.10s %5u",
  417.               rec.marker== 0xaa?"Get:":"PUT:",
  418.               rec.seg,
  419.               rec.hour,rec.min,rec.sek,rec.hund,
  420.               rec.nopara*16,rec.file,rec.line);
  421.       if (rec.marker == '\x55')   {
  422.          fread(&ai,sizeof(Ainf),1,fpi);
  423.          fprintf(fpo,"%10.10s %5u\n",ai.file,ai.line);
  424.       } else
  425.          fprintf(fpo,"\n");
  426.    }
  427. }
  428. /*----------------------------------------------------------------------*
  429. *-----------------------------------------------------------------------*/
  430.  
  431. void usage(void)
  432. {
  433.    printf("Usage: analmem [infile] | -d[infile] | -r[infile]\n");
  434.    printf("\tfor default and -m  a memory record file is expected\n");
  435.    printf("\tfor             -d  a dump data set is expected\n");
  436.    exit(2);
  437. }
  438.  
  439. /*----------------------------------------------------------------------*
  440. *-----------------------------------------------------------------------*/
  441. static void near dline(FILE *fp)
  442. {
  443. int i;
  444.    fputc('\n',fp);
  445.    for(i=0;i<79;i++)    {
  446.       fputc('=',fp);
  447.    }
  448. }
  449. /*----------------------------------------------------------------------*
  450. *-----------------------------------------------------------------------*/
  451. static void near xline(FILE *fp)
  452. {
  453. int i;
  454.    fputc('\n',fp);
  455.    for(i=0;i<39;i++)    {
  456.       fputc('=',fp);
  457.       fputc('.',fp);
  458.    }
  459. }
  460. /*----------------------------------------------------------------------*
  461. *-----------------------------------------------------------------------*/
  462. #define ERR(s, c)       if(opterr){\
  463.         extern int write();\
  464.         char errbuf[2];\
  465.         errbuf[0] = c; errbuf[1] = '\n';\
  466.         (void) write(2, argv[0], (unsigned)strlen(argv[0]));\
  467.         (void) write(2, s, (unsigned)strlen(s));\
  468.         (void) write(2, errbuf, 2);}
  469.  
  470.  
  471. /*----------------------------------------------------------------------*
  472. *-----------------------------------------------------------------------*/
  473. int getopt(int  argc,char **argv,char *opts)
  474. {
  475. static int sp = 1;
  476. register int c;
  477. register char *cp;
  478.  
  479.    if(sp == 1)
  480.       if(optind >= argc         ||
  481.          argv[optind][0] != '-' ||
  482.          argv[optind][1] == '\0')
  483.          return(EOF);
  484.       else if(strcmp(argv[optind], "--") == 0) {
  485.          optind++;
  486.          return(EOF);
  487.       }
  488.    optopt = c = argv[optind][sp];
  489.    if(c == ':' || (cp=strchr(opts, c)) == NULL) {
  490.       ERR(": illegal option -- ", c);
  491.       if(argv[optind][++sp] == '\0') {
  492.          optind++;
  493.          sp = 1;
  494.       }
  495.       return('?');
  496.    }
  497.    if(*++cp == ':') {
  498.       if(argv[optind][sp+1] != '\0')
  499.          optarg = &argv[optind++][sp+1];
  500.       else if(++optind >= argc) {
  501.          ERR(": option requires an argument -- ", c);
  502.          sp = 1;
  503.          return('?');
  504.       } else
  505.          optarg = argv[optind++];
  506.       sp = 1;
  507.    } else {
  508.       if(argv[optind][++sp] == '\0') {
  509.          sp = 1;
  510.          optind++;
  511.       }
  512.       optarg = NULL;
  513.    }
  514.    return(c);
  515. }
  516.  
  517. /*----------------------------------------------------------------------*
  518. * Extract a byte from a short *
  519. *-----------------------------------------------------------------------*/
  520. #define hibyte(x)       ((unsigned char)((x) >> 8))
  521. #define lobyte(x)       ((unsigned char)(x))
  522.  
  523. /*----------------------------------------------------------------------*
  524. * Extract nibbles from a byte                                           *
  525. *-----------------------------------------------------------------------*/
  526. #define hinibble(x)     (((x) >> 4) & 0xf)
  527. #define lonibble(x)     ((x) & 0xf)
  528.  
  529.  
  530. /*----------------------------------------------------------------------*
  531. *-----------------------------------------------------------------------*/
  532. /* Print a buffer up to 16 bytes long in formatted hex with ascii
  533.  * translation, e.g.,
  534.  * 0000: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f  0123456789:;<=>?
  535.  */
  536. static void fmtline(unsigned addr,char *buf,unsigned len,char *line)
  537. {
  538. register char *aptr,*cptr;
  539. register char c;
  540.  
  541.    memset(line,' ',81);
  542.    ctohex(line,(unsigned)hibyte(addr));
  543.    ctohex(line+2,(unsigned)lobyte(addr));
  544.    aptr = &line[6];
  545.    cptr = &line[55];
  546.    while(len-- != 0){
  547.       c = *buf++;
  548.       ctohex(aptr,(unsigned)(c));
  549.       aptr += 3;
  550.       c &= 0x7f;
  551.       *cptr++ = isprint((c)) ? c : '.';
  552.    }
  553.    *cptr++ = '\0';
  554. }
  555. /* Convert byte to two ascii-hex characters */
  556. static void ctohex(register char *buf,register unsigned c)
  557. {
  558.    static char hex[] = "0123456789abcdef";
  559.  
  560.    *buf++ = hex[hinibble(c)];
  561.    *buf = hex[lonibble(c)];
  562. }
  563.  
  564.  
  565.